﻿using NetFrame.AbsClass;
using NetFrame.EnDecode;
using System;
using System.Collections.Generic;
using System.Net.Sockets;
using System.Text;

namespace NetFrame {
    public delegate void SendDE(SocketAsyncEventArgs e);
    public delegate void CloseToken(BaseToken token, string error);

    /// <summary>
    /// 自定义连接对象
    /// </summary>
    public class BaseToken {

        public SocketAsyncEventArgs read_args, write_args;

        public Socket socket;

        public AbsMessageCenter center;

        public SendDE send_de;//发送数据完成后委托
        public CloseToken close_de;

        //消息的接收缓存
        public List<byte> cache = new List<byte>();

        //写消息队列
        public Queue<TransModel> wqueue = new Queue<TransModel>();

        public bool isWrite = false,isRead=false;

        //编码解码器
        BaseCode code;

        public BaseToken() {
            read_args = new SocketAsyncEventArgs();
            write_args = new SocketAsyncEventArgs();

            //设定异步操作的缓冲区
            read_args.SetBuffer(new byte[1024], 0, 1024);

            read_args.UserToken = this;
            write_args.UserToken = this;

            code = new BaseCode();
        }

        /// <summary>
        /// 接收数据
        /// </summary>
        /// <param name="data"></param>
        public void Recevice(byte[] data) {
            cache.AddRange(data);
            Read();
        }

        /// <summary>
        /// 处理缓冲区cache的数据
        /// </summary>
        public void Read() {
            try {
                //string content = Encoding.UTF8.GetString(cache.ToArray());
                //if (content == null) {
                //    return;
                //}

                TransModel model = code.Decoding(ref cache);

                if (model == null) {
                    isRead = false;
                    return;
                }

                //通知上层应用 消息到达
                center.OnMessageReceive(this, model);
                cache.Clear();
            }
            catch (Exception ex) {
                return;
            }



        }

        /// <summary>
        /// 发送传输模型
        /// </summary>
        /// <param name="model"></param>
        public void Send(TransModel model) {
            wqueue.Enqueue(model);
            if (!isWrite) {
                isWrite = true;
                Write();
            }
        }

        /// <summary>
        /// 向对应socket发送消息
        /// </summary>
        public void Write() {
            if (wqueue.Count <= 0) {
                isWrite = false;
                return;
            }

            //string content = wqueue.Dequeue();
            //byte[] value = Encoding.UTF8.GetBytes(content);
            TransModel model = wqueue.Dequeue();
            byte[] value = code.Encoding(model);
            if (value == null) {
                isWrite = false;
                return;
            }

            write_args.SetBuffer(value, 0, value.Length);

            try {
                bool v = socket.SendAsync(write_args);
                if (!v) {
                    send_de(write_args);

                }
            }
            catch (Exception ex) {
                Console.WriteLine(ex.ToString());
                close_de(this, "发送数据失败");
            }

        }



        public void Close() {
            try {
                socket.Shutdown(SocketShutdown.Both);
                socket.Dispose();
                socket = null;
            }
            // throws if client process has already closed
            catch (Exception ex) {
                Console.WriteLine(ex.ToString());
            }

        }

    }
}
